import os
import json
import requests
import pytest
from pytest import main

# 加载Swagger配置获取API文档URL
config_path = os.path.join(os.path.dirname(__file__), "../config/swagger_config.json")
with open(config_path, 'r', encoding='utf-8') as f:
    swagger_config = json.load(f)
SWAGGER_URL = swagger_config.get('swagger_url', 'http://localhost:19078/apispec_1.json')

# 获取Swagger API文档
def get_swagger_json():
    try:
        response = requests.get(SWAGGER_URL, timeout=10)
        response.raise_for_status()
        return response.json()
    except Exception as e:
        pytest.fail(f"获取Swagger文档失败: {str(e)}")

# 生成测试用例
swagger_data = get_swagger_json()
servers = swagger_data.get('servers', [{'url': 'http://localhost:19078'}])
base_url = servers[0]['url']
test_cases = []

for path, methods in swagger_data.get('paths', {}).items():
    for method, details in methods.items():
        test_cases.append({
            'path': path,
            'method': method.upper(),
            'details': details,
            'name': details.get('summary', f"{method} {path}")
        })


# 执行API测试
@pytest.mark.parametrize("test_case", test_cases)
def test_api_endpoints(test_case):
    url = f"{base_url}{test_case['path']}"
    method = test_case['method']
    params = {}
    json_data = {}

    # 提取参数信息
    if 'parameters' in test_case['details']:
        for param in test_case['details']['parameters']:
            if param['in'] == 'query':
                params[param['name']] = param.get('example', f"test_{param['name']}")

    # 提取请求体示例
    if 'requestBody' in test_case['details']:
        content = test_case['details']['requestBody'].get('content', {})
        if 'application/json' in content:
            json_data = content['application/json'].get('example', {})

    # 发送请求
    try:
        response = requests.request(
            method, url, params=params, json=json_data, timeout=10
        )
        # 验证响应状态码
        assert response.status_code in [200, 201, 204], \
            f"{method} {url} 失败: 状态码 {response.status_code}"
    except Exception as e:
        pytest.fail(f"{method} {url} 执行错误: {str(e)}")


if __name__ == "__main__":
    # 生成HTML测试报告
    main(["-v", "--html=test_report.html", __file__])